/*
图书管理系统，控制台形式，书籍有书名，作者，售价三个属性，要求有增删改查4个功能，且执行完每个功能后，菜单循环显示，有退出功能。数据持久存储
 */
package javaio.BookManagement;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

    private static List<Book> LIST = new ArrayList<>(); //使用一个List暂存书籍信息

    public static void main(String[] args) {
        loadData();
        Scanner scanner = new Scanner(System.in);  //使用扫描器接受用户输入，后面根据用户的输入做判断
        //循环打印几个选项，根据用户选择的不同选项，执行不同的操作
        while (true){
            System.out.println("===============图书管理系统================");
            System.out.println("1.添加书籍信息");
            System.out.println("2.修改书籍信息");
            System.out.println("3.查询书籍信息");
            System.out.println("4.删除书籍信息");
            System.out.println("按其他任意键退出系统");

            String input = scanner.nextLine();  //用户敲了之后肯定要换行，所以用netLine(),用input接收输入
            switch (input) {
                case "1":
                    insertBook(scanner);
                    break;
                case "2":
                    modifyBook(scanner);
                    break;
                case "3":
                    showBook();
                    break;
                case "4":
                    deleteBook(scanner);
                    break;

                default:
                    saveData();
                    scanner.close(); //把扫描器关一下
                    return;  //默认执行return操作，return到while循环，而不是用break跳出while循环

            }
        }

    }
    //要对书籍进行操作，肯定要先定义一个书籍类，书籍的属性是它的成员变量
    private static class Book implements Serializable{  //不实现序列化，保存会出错
        String name;
        String author;
        double price;
        //不想保存某个属性，可以用transient关键字，结束后就不会保存这个属性，打开时这个属性也是基本类型的默认值

        /*
        public Book(String name, String author, double price) {  //使用邮件Generate快速生成构造方法
            this.name = name;
            this.author = author;
            this.price = price;
        }

         */
        //我们使用另一种构造方法的编写方式，方便在添加编辑书籍时支持链式调用处理书籍名、作者信息、价格。
        public Book name(String name){
            this.name = name;
            return this;
        }

        public Book author(String author){
            this.author = author;
            return this;
        }

        public Book price(double price){
            this.price = price;
            return this;
        }


        //println打印的时候要调用Book的toString()方法，使用Generate重新toString方法
        @Override
        public String toString() {
            return "书籍{" +
                    "名称='" + name + '\'' +
                    ", 作者='" + author + '\'' +
                    ", 价格=" + price +
                    '}';
        }
    }

    private static void insertBook(Scanner scanner){
        /* 一般写法
        Book book = new Book();  //先创建一本书
        book  //链式调用
                .name(scanner.nextLine())  //接收输入的书名
                .author(scanner.nextLine())  //接收输入的作者
                .price(scanner.nextDouble());  //接收输入的价格
        list.add(book);
        */
        //更精简的写法,一行就解决了，下面链式调用可以看成1行，可以写成1行
        LIST.add( new Book()
                .name(scanner.nextLine())  //接收输入的书名
                .author(scanner.nextLine())  //接收输入的作者
                .price(scanner.nextDouble()));  //接收输入的价格

        scanner.nextLine(); //吸收最后一个换行
    }

    private static void showBook(){
        LIST.forEach(System.out::println);  //println要调用Book的toString()方法，所以Book类里要重写toString()方法
    }

    //删除书籍
    private static void deleteBook(Scanner scanner){
        int i = 0;

        for (Book book : LIST) System.out.println(i+"."+ book);

        int index = scanner.nextInt(); //扫描用户输入的要删除的编号
        if(index >= LIST.size()) System.out.println("错误的序号");
        else LIST.remove(i);  //remove()方法支持按索引下标删除
        scanner.nextLine(); //吸收换行符
    }

    //修改书籍
    private static void modifyBook(Scanner scanner){
        int i = 0;
        for (Book book: LIST) System.out.println(i+"."+book);
        int index = scanner.nextInt();
        scanner.nextLine(); //吸收空行
        if(index >= LIST.size()) System.out.println("错误的序号");
        else {
            LIST.get(index)
                    .name(scanner.nextLine())
                    .author(scanner.nextLine())
                    .price(scanner.nextDouble());
        }

        scanner.nextLine(); //吸收空行

    }

    //打开时加载数据
    private static void loadData(){
        //判断有没有data
        File file = new File("data");
        if (file.exists()){
            try(ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("data"))){
                LIST = (List<Book>) objectInputStream.readObject();  //根据报错提示转换类型

            }catch (IOException | ClassNotFoundException e){
                e.printStackTrace();
            }
        }else {
            LIST = new ArrayList<>();
        }

    }

    //退出时保存数据的方法
    private static void saveData(){
        try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("data"))){
            objectOutputStream.writeObject(LIST);
            objectOutputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
